{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Working with jobs\n", "\n", "The job class obtained after running a QuantumCircuit has interesting properties that can be used." ] }, { "cell_type": "code", "execution_count": 10, "outputs": [], "source": [ "import os\n", "from c12_callisto_clients.user_configs import UserConfigs\n", "from c12_callisto_clients.qiskit.c12sim_provider import C12SimProvider\n", "from qiskit import QuantumCircuit" ], "metadata": { "collapsed": false, "ExecuteTime": { "end_time": "2024-10-08T14:47:38.763647Z", "start_time": "2024-10-08T14:47:38.760435Z" } } }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false, "ExecuteTime": { "end_time": "2024-10-08T14:41:33.856585Z", "start_time": "2024-10-08T14:41:33.531695Z" } }, "outputs": [ { "data": { "text/plain": " ┌───┐ \nq_0: ┤ H ├──■──\n └───┘┌─┴─┐\nq_1: ─────┤ X ├\n └───┘", "text/html": "
┌───┐ \nq_0: ┤ H ├──■──\n └───┘┌─┴─┐\nq_1: ─────┤ X ├\n └───┘" }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\n", "TOKEN = os.getenv(\"C12_TOKEN\")\n", "configs = UserConfigs.parse_obj({\"token\" : TOKEN})\n", "c12_simulator_provider = C12SimProvider(configs)\n", "c12_simulator_backend = c12_simulator_provider.get_backend('c12sim-iswap')\n", "circuit = QuantumCircuit(2)\n", "circuit.h(0)\n", "circuit.cx(0, 1)\n", "\n", "circuit.draw()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Two main methods available for each Job instance are job_id() and status().\n", "\n", "1. `job_id()` method returns the unique identifier of a job as a UUID4 string (a universally unique identifier (UUID), version 4, is a 36-character alphanumeric random generated string). This id can be used for later assessment of the job properties.\n", "\n", "2. `status()` method is used to get the status of a job execution as an instance of JobStatus class. Available statuses are:\n", " - `QUEUED` = Job is queued. It waits for execution\n", " - `RUNNING` = Job is currently running.\n", " - `CANCELLED` = Job has been canceled.\n", " - `DONE` = Job has been successfully done.\n", " - `ERROR` = There has been an error during the execution of a job.\n", "\n", "The status of a running job can be changed depending on the current state of job execution.\n" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false, "ExecuteTime": { "end_time": "2024-10-08T14:34:27.494363Z", "start_time": "2024-10-08T14:34:27.074318Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Job id: 25f3fecf-f0b2-4f03-bf4c-bbf35234c1e9\n", "Status: JobStatus.RUNNING\n" ] } ], "source": [ "c12_job = c12_simulator_backend.run(circuit)\n", "\n", "print(f\"Job id: {c12_job.job_id()}\") # Get a job UUID\n", "print(f\"Status: {c12_job.status()}\") # Get a current job status" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The result of a job execution can be obtained with the `result()` method. This method can have one optional argument (timeout). The `timeout` argument specifies how long the method will wait for the execution of the task. If the time limit is exceeded, the `C12SimJobError` exception is raised. If we do not specify this argument, its default value is None, meaning the method will block until the simulation is finished.\n", "\n", "Another way to get the results is to check the job status periodically until it is `DONE` and then call the `result()` function." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false, "ExecuteTime": { "end_time": "2024-10-08T14:35:18.370737Z", "start_time": "2024-10-08T14:34:31.252430Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "25f3fecf-f0b2-4f03-bf4c-bbf35234c1e9: JobStatus.RUNNING\n", "25f3fecf-f0b2-4f03-bf4c-bbf35234c1e9: JobStatus.RUNNING\n", "25f3fecf-f0b2-4f03-bf4c-bbf35234c1e9: JobStatus.RUNNING\n", "25f3fecf-f0b2-4f03-bf4c-bbf35234c1e9: JobStatus.RUNNING\n", "25f3fecf-f0b2-4f03-bf4c-bbf35234c1e9: JobStatus.RUNNING\n", "25f3fecf-f0b2-4f03-bf4c-bbf35234c1e9: JobStatus.RUNNING\n", "25f3fecf-f0b2-4f03-bf4c-bbf35234c1e9: JobStatus.RUNNING\n", "25f3fecf-f0b2-4f03-bf4c-bbf35234c1e9: JobStatus.RUNNING\n", "25f3fecf-f0b2-4f03-bf4c-bbf35234c1e9: JobStatus.RUNNING\n", "25f3fecf-f0b2-4f03-bf4c-bbf35234c1e9: JobStatus.DONE\n", "{'00': 507, '01': 2, '10': 1, '11': 514}\n" ] } ], "source": [ "from qiskit.providers import JobStatus\n", "import time\n", "job_final_states = [JobStatus.DONE, JobStatus.ERROR, JobStatus.CANCELLED]\n", "c12_job_id = c12_job.job_id()\n", "while True:\n", " job_status = c12_job.status()\n", " print(f'{c12_job_id}: {job_status}')\n", " if job_status in job_final_states:\n", " break\n", " time.sleep(5) # Wait 5 s\n", "\n", "if c12_job.status() == JobStatus.DONE:\n", " c12_result = c12_job.result()\n", " print(c12_result.get_counts())" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false, "ExecuteTime": { "end_time": "2024-10-08T14:36:16.544056Z", "start_time": "2024-10-08T14:35:23.888714Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'00': 514, '11': 510}\n" ] } ], "source": [ "# Running a job that will block until finished\n", "c12_job = c12_simulator_backend.run(circuit)\n", "c12_result = c12_job.result()\n", "if c12_job.status() == JobStatus.DONE:\n", " print(c12_result.get_counts())" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false, "ExecuteTime": { "end_time": "2024-10-08T14:37:07.957500Z", "start_time": "2024-10-08T14:36:51.562765Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Timeout!\n", " Last status: JobStatus.RUNNING\n" ] } ], "source": [ "# Getting a job result with a timeout argument specified\n", "from c12_callisto_clients.qiskit.exceptions import C12SimJobError\n", "c12_job = c12_simulator_backend.run(circuit)\n", "\n", "try:\n", " c12_result = c12_job.result(timeout=15) # it will raise a C12SimJobError as it won't be finished in 15s\n", "except C12SimJobError:\n", " print(\"Timeout!\")\n", " print(f\" Last status: {c12_job.status()}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Getting previous jobs\n", "\n", "Next, an extremely useful functionality is the possibility to obtain all jobs run on the system by a specific user. Using this functionality, the user can get the results of old jobs.\n", "\n", "This can be achieved by calling the `jobs()` function on the backend instance. This function accepts two arguments: `limit` and `offset`. We can specify how many jobs we want to get with a `limit` argument. Likewise, we can set the `offset` from the first job with an offset argument. With these arguments, pagination is easily achieved." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false, "ExecuteTime": { "end_time": "2024-10-08T14:41:49.808817Z", "start_time": "2024-10-08T14:41:47.513320Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1: 8f1a598d-5efa-46df-89f5-fc4c69e38d46 Status: JobStatus.DONE\n", "2: 46b62950-e1a3-4750-a8e1-75d738fe4d07 Status: JobStatus.DONE\n", "3: 84af6995-ff3d-459f-ab9c-89fa90603f43 Status: JobStatus.DONE\n", "4: ca23490d-c820-4529-abd2-801cf313eaf8 Status: JobStatus.DONE\n", "5: 4e8ec2e8-1d16-4bd4-a87c-8bc8c9ea7420 Status: JobStatus.DONE\n", "6: d609a2d1-de33-48ea-adfc-c4b4d0e1afd9 Status: JobStatus.DONE\n", "7: ff507df5-65ff-410f-a20e-b4e86726dab8 Status: JobStatus.DONE\n", "8: d79259bd-3304-41e2-98e8-3a1794cf6dff Status: JobStatus.DONE\n", "9: 9bf33018-e427-4ae6-a4e8-698a21ab60b3 Status: JobStatus.DONE\n", "10: dd2ae9e8-6e0c-4a1f-b753-da651d6a4011 Status: JobStatus.DONE\n" ] } ], "source": [ "number_of_records = 10\n", "offset = 10\n", "counter = 1\n", "\n", "jobs = c12_simulator_backend.jobs(number_of_records, offset)\n", "\n", "for job in jobs:\n", " print(f\"{counter}: {job.job_id()} Status: {job.status()}\")\n", " counter += 1\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For each job, it is possible to get the circuit sent to the simulator for execution. But, it is even possible to get the transpiled version of this circuit to see what the circuit has been run after the transpilation process." ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false, "ExecuteTime": { "end_time": "2024-10-08T14:41:54.385726Z", "start_time": "2024-10-08T14:41:53.280808Z" } }, "outputs": [ { "data": { "text/plain": "